package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"strconv"
	"time"
)

var baseURL *url.URL

func httpGet(path string) (interface{}, error) {
	var u = *baseURL
	u.Path = baseURL.Path + path
	resp, err := http.Get(u.String())
	if err != nil {
		return nil, err
	}
	bs, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	var data map[string]interface{}
	err = json.Unmarshal(bs, &data)
	if err != nil {
		return nil, err
	}
	if no, ok := data["no"].(float64); ok && no == 200 {
		return data["data"], nil
	}
	return nil, errors.New(fmt.Sprint(data["msg"]))
}

func httpPost(path string, body map[string]interface{}) (interface{}, error) {
	var u = *baseURL
	u.Path = baseURL.Path + path
	var values = url.Values{}
	for k, v := range body {
		switch t := v.(type) {
		case int:
			values[k] = []string{strconv.FormatInt(int64(t), 10)}
		case int32:
			values[k] = []string{strconv.FormatInt(int64(t), 10)}
		case int64:
			values[k] = []string{strconv.FormatInt(t, 10)}
		case float32:
			values[k] = []string{strconv.FormatFloat(float64(t), 'f', -1, 64)}
		case float64:
			values[k] = []string{strconv.FormatFloat(t, 'f', -1, 64)}
		case string:
			values[k] = []string{t}
		case time.Time:
			values[k] = []string{strconv.FormatInt(t.UnixNano()/1e6, 10)}
		default:
			bs, err := json.Marshal(t)
			if err == nil {
				values[k] = []string{string(bs)}
			}
		}
	}
	resp, err := http.PostForm(u.String(), values)
	if err != nil {
		return nil, err
	}
	bs, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	var data map[string]interface{}
	err = json.Unmarshal(bs, &data)
	if err != nil {
		return nil, err
	}
	if no, ok := data["no"].(float64); ok && no == 200 {
		return data["data"], nil
	}
	return nil, errors.New(fmt.Sprint(data["msg"]))
}

func CheckPort(port int) error {
	var err error

	tcpAddress, err := net.ResolveTCPAddr("tcp4", fmt.Sprintf(":%d", port))
	if err != nil {
		return err
	}

	for i := 0; i < 3; i++ {
		listener, err := net.ListenTCP("tcp", tcpAddress)
		if err != nil {
			time.Sleep(100 * time.Millisecond)
			if i == 3 {
				return err
			}
			continue
		} else {
			listener.Close()
			break
		}
	}

	return nil
}
